package com.echo.blog.business.oauth.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.echo.blog.business.sys.model.RegisterUserVo;
import com.echo.blog.business.sys.model.SysUser;
import com.echo.blog.business.sys.service.ISysUserService;
import com.echo.blog.core.properties.Oauth2ClientProperties;
import com.echo.blog.core.utils.RestClient;
import com.echo.model.constant.CacheKey;
import com.echo.model.constant.ConstantUtils;
import com.echo.model.constant.response.ResponseData;
import com.echo.model.context.LoginUser;
import com.echo.model.exception.CustomException;
import com.echo.model.resq.response.UcenterCode;
import com.echo.model.utils.StringUtils;
import com.echo.model.utils.ToolUtil;
import com.echo.model.utils.ValueUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @version: V1.0
 * @author: chentailai
 * @description: Oauth2 控制器（主要用于获取用户信息）
 * @className: OauthController
 * @data: 2020/3/30 17:42
 **/
@Slf4j
@RestController
@RequestMapping("/auth")
public class OauthController {

    //用户默认的头像
    public static final String DEFAULT_AVATAR_URL = "http://111.231.239.202:8018/data/img/noface.jpg";
    @Resource
    private RestClient restClient;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private Oauth2ClientProperties clientProperties;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @GetMapping("user")
    public Principal user(Principal principal) {
        return principal;
    }

    @PostMapping("/login")
    public ResponseData loginByPassword(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("redirect_url") String redirect_url, HttpServletRequest req) {
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> userMap = new HashMap<>();

        String frontPassword = new String(Base64.getDecoder().decode(password.getBytes()));

        log.info("当前请求登录的用户:{}，输入的密码:{},重定向地址:{}", username, frontPassword, redirect_url);

        SysUser sysUser = sysUserService.getUserByName(username);
        if (sysUser == null) {
            //验证1： 系统中不存在此用户
            throw new CustomException(UcenterCode.UCENTER_ACCOUNT_NOTEXISTS);
        }

        //md5 处理密码
        String salt = sysUser.getSalt();
        String backendPassword = ToolUtil.md5Hex(frontPassword, salt);
        sysUser.setPassword(backendPassword);

        //请求授权服务器 的token发放端点
        JSONObject res = restClient.getOauthTokenByPasswordMode(sysUser, JSONObject.class);
        log.info("从授权服务器获取 token信息成功,{}", res.toJSONString());
        String access_token = ValueUtils.parseString(res.get("access_token"));
        //组装返回值
        userMap.put("name", sysUser.getName());
        userMap.put("username", sysUser.getUsername());
        userMap.put("avatar", StringUtils.isEmpty(sysUser.getAvatar()) ? DEFAULT_AVATAR_URL : sysUser.getAvatar());
        userMap.put("signature", sysUser.getSignature());
        result.put("access_token", access_token);
        result.put("user_info", userMap);

        LoginUser loginUser = new LoginUser(sysUser.getUsername(), sysUser.getName(), sysUser.getId());
        //添加全局登录的用户
        BoundValueOperations<String, Object> opts = redisTemplate.boundValueOps(CacheKey.USER_KEY + access_token);
        opts.set(loginUser, ConstantUtils.Public.TWO_HOURS, TimeUnit.SECONDS);
        log.info("用户信息已缓存，key:{}", JSON.toJSONString(CacheKey.USER_KEY + access_token));

        return ResponseData.success(200, "登陆成功", result);
    }

    @PostMapping("/register")
    public ResponseData registerUser(@Validated RegisterUserVo registerUserVo) {
        String frontPassword = new String(Base64.getDecoder().decode(registerUserVo.getPassword().getBytes()));
        String salt = ToolUtil.getRandomString(4);

        String name = registerUserVo.getName();
        String username = registerUserVo.getUsername();
        String password = ToolUtil.md5Hex(frontPassword, salt);
        String signature = registerUserVo.getSignature();
        String phone = registerUserVo.getPhone();
        String address = registerUserVo.getAddress();
        String sex = registerUserVo.getSex();
        Integer age = registerUserVo.getAge();
        String avatar = registerUserVo.getAvatar();

        //用户是否存在
        SysUser sysUserDb = sysUserService.getUserByName(username);
        if (sysUserDb != null) {
            return ResponseData.error("该用户名 " + username + " 已存在");
        }

        SysUser sysUser = new SysUser(username,
                name,
                password,
                salt,
                signature,
                phone,
                address,
                sex,
                age,
                avatar,
                "CUSTOMER"
        );
        sysUserService.save(sysUser);


        return ResponseData.success(200, "注册成功", sysUser);
    }


}